<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\extend;


use JetBrains\PhpStorm\Pure;

/**
 * 微信api基类
 * Class wechat
 * @package app\library
 */
class MiCurl
{

    private static ?self $_instance = null;

    public string $result = '';

    private bool $isForceSSL = false;

    private $cert;

    public static function instance(): MiCurl
    {
        if (!self::$_instance){
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    public function useCert($cert): static
    {
        $this->isForceSSL = true;
        $this->cert = $cert;
        return $this;
    }

    /**
     * 模拟GET请求 HTTPS的页面
     * @param string $url 请求地址
     * @param array $data
     * @throws \Exception
     */
    public function get(string $url, array $data = []): static
    {
        // 处理query参数
        if (!empty($data)) {
            $url = $url . '?' . http_build_query($data);
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
        $result = curl_exec($curl);
        if ($result === false) {
            throw new \Exception(curl_error($curl));
        }
        curl_close($curl);
        $this->result = $result;
        return $this;
    }

    /**
     * 模拟POST请求
     * @param string $url 请求地址
     * @param null|array $data 请求数据
     * @param false $useCert 是否引入微信支付证书
     * @param array $sslCert 证书路径
     * @throws \Exception
     */
    public function post(string $url, null|array|string $data = [], $header=''): static
    {
        if (!$header){
            $header = [
                'Content-type: application/json;'
            ];
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_POST, TRUE);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        if ($this->isForceSSL == true) {
            // 设置证书：cert 与 key 分别属于两个.pem文件
            curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLCERT, $this->cert['certPem']);
            curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLKEY, $this->cert['keyPem']);
        }
        $result = curl_exec($curl);
        if ($result === false) {
            throw new \Exception(curl_error($curl));
        }
        curl_close($curl);
        $this->result = $result;
        return $this;
    }

    /**
     * 模拟POST请求 [第二种方式, 用于兼容微信api]
     * @param $url
     * @param array $data
     * @throws \Exception
     */
    public function post2($url, array $data = []): static
    {
        $header = [
            'Content-Type: application/x-www-form-urlencoded'
        ];
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
        $result = curl_exec($ch);
        if ($result === false) {
            throw new \Exception(curl_error($ch));
        }
        curl_close($ch);
        $this->result = $result;
        return $this;
    }

    public function toJson(): string
    {

        return $this->result;
    }

    public function toArray(){
        return json_decode($this->result, true);
    }


}
